Python provides features like lambda, filter, map, and reduce that can basically cover most of what you would need to know about Functional Programming.
For detailed analysis, please see the accompanying blog titled:Elements of Functional Programming in Python
Lambda expressions - also known as "anonymous functions" - allow us to create and use a function in a single line. They are useful when we need a short function that will be used only once.
They are mostly used in conjunction with the map, filter and the sort methods, which we will see later in the article.
Let's write a function in Python, that will compute the value of 5x + 2. The standard approach would be to define a function.
In [5]:
def f(x):
"""Function to compute the value of 5x+2"""
return 5*x+2
f(3)
Out[5]:
Now we would compute the same expression using Lambda functions. To create a lambda expression, we type in the keyword lambda, followed by the inputs. Next, we enter a colon followed by the expression that will be the return value.
In [6]:
lambda x: 5*x+2
Out[6]:
This lambda function will take the input x and return 5x + 2, just like the earlier function f. There is a problem, however.The lambda is not the name of the function. It is a Python keyword that says - what follows is an anonymous function. So how do we use it? One way is to give it a name. Let us call this lambda expression g. Now, you can use this like any other function.
In [7]:
g = lambda x: 5*x+2
g(3)
Out[7]:
In [20]:
# Calculating Harmonic Mean using lambda function
harmonic_mean = lambda x,y,z : 3/(1/x + 1/y + 1/z)**0.5
harmonic_mean(1,2,3)
Out[20]:
let's look at a common use of Lambda function where we do not assign it a name. Let's say we have a list of the first seven U.S Presidents and we'd like to sort this list by their last name. We shall create a Lambda function that extracts the last name, and uses that as the sorting value.
In [21]:
# Sorting a List by thr last name using lambda expression
In [22]:
presidents_usa = ["George Washington", "John Adams","Thomas Jefferson","James Madison","James Monroe","John Quincy Adams","Andrew Jackson"]
presidents_usa.sort(key = lambda name: name.split(" ")[-1].lower())
presidents_usa
Out[22]:
In [25]:
def volume(a):
"""volumne of a cube with edge 'a'"""
return a**3
What if we need to compute the volumes for many different cubes with different edge lengths?
In [26]:
# Edge length in cm
edges = [1,2,3,4,5]
There are two ways to do this. One by using the direct method
and the other by using the map
function.
In [27]:
# Calculating the volume of given cubes using Direct Method
volumes = []
for a in edges:
v = volume(a)
volumes.append(v)
volumes
Out[27]:
Now let's see how we can accomplish this task using a single line of code with the map function.
In [29]:
# Calculating the volume of given cubes using the Map function
map(volume,edges)
Out[29]:
The map function takes in two arguments. The first is a function, and the second is your list, tuple, or any other iterable object. Here, the map function applies the volume function to each element in the list.
However, an important thing to note here is that the output of the map function is not a list but a map object, which is actually an iterator over the results. We can, however, turn this into a list by passing the map to the list constructor.
In [31]:
list(map(volume,edges))
Out[31]:
Let's now see an example which demonstrates the use of lambda
function with the map
function. We have a list of tuples containing name and heights for 5 people. Each of the height is in centimeters and we need to convert it into feet.
We will first write a converter function using a lambda expression which will accept a tuple as the input and will return a tuple with the same name.
In [32]:
# Convert height from cms to feet : 1 cm = 0.0328 feet
height_in_cms = [('Tom',183),('Daisy',171),('Margaret',179),('Michael',190),('Nick',165)]
#Writing Convertor function using lambda expression
height_in_feet = lambda data: (data[0],round(data[1]*0.0328,1))
#Using the 'Map' function
list(map(height_in_feet,height_in_cms))
Out[32]:
The filter
function constructs an iterator from those elements of iterable for which function returns true. This means filter function is used to select certain pieces of data from a list, tuple, or other collection of data, hence the name.
filter(filter(function, iterable)
In [33]:
# Filter out all the numbers greater than 5 from a list
my_list = [1,2,3,4,5,6,7,8,9]
output_list = filter(lambda x : x>5, my_list)
list(output_list)
Out[33]:
Here is a list containing some of the countries in Asia. Notice there are numerous strings that are empty. We'll use the filter function to remove these missing values. We'll simply pass none as the first argument and the second argument is the list of data as before.
In [34]:
# Removing missing values from a list
countries_asia = ["Afghanistan","","Bhutan","","China","","Georgia","","","India"]
list(filter(None,countries_asia))
Out[34]:
This filters out all values that are treated as false in a boolean setting.
The Reduce
function is a bit unusual and in fact, as of Python 3, it is no longer a built-in function. Instead, it has been moved to the functools module.
The 'reduce' function transforms a given list into a single value by applying a function cumulatively to the items of sequence, from left to right,
reduce(func, seq)
where reduce continually applies the function func() to the sequence seq and returns a single value.
In [36]:
# Compute the product of a list of integers using 'reduce'function
from functools import reduce
product = reduce((lambda x,y : x*y), [1,2,3,4,5])
product
Out[36]:
The following diagram shows the intermediate steps of the calculation:
The above program can also be written with an explicit for loop which is more clear.Hence Use functools.reduce if you really need it
In [38]:
# Compute the product of a list of integers using a 'For' loop
product = 1
list = [1,2,3,4,5]
for num in list:
product = product*num
product
Out[38]:
In [42]:
# Determining the maximum number in a given list
from functools import reduce
f = lambda a,b : a if (a>b) else b
reduce(f,[58,69,12,158,698])
Out[42]:
List comprehension is a way to define and create lists in Python. in most cases, list comprehensions let us create lists in a single line of code without worrying about initializing lists or setting up loops.
It is also a substitute for the lambda function as well as the functions map()
, filter()
and reduce()
. Some people find it a more pythonic way of writing functions and find it easier to understand.
In [44]:
# Creating a list of squares of first 10 numbers using loops
squares = []
for x in range(10):
squares.append(x**2)
squares
Out[44]:
Now let's use list comprehension to achieve the same result in a one liner
In [45]:
# # Creating a list of squares of first 10 using list comprehension
squares = [x**2 for x in range(10)]
squares
Out[45]:
Let's try and replicate the examples used in the above sections with list comprehensions.
In [46]:
# Convert height from cms to feet using List Comprehension : 1 cm = 0.0328 feet
height_in_cms = [('Tom',183),('Daisy',171),('Margaret',179),('Michael',190),('Nick',165)]
height_in_feet = [(height[0],round(height[1]*0.0328,1)) for height in height_in_cms]
height_in_feet
Out[46]:
In [47]:
# Removing missing values from a list
countries_asia = ["Afghanistan","","Bhutan","","China","","Georgia","","","India"]
[country for country in countries_asia if country!=""]
Out[47]:
In [49]:
# Determining the maximum number in a given list
numbers = [58,69,12,158,698,956]
max((x) for x in numbers)
Out[49]:
In [ ]: